package com.qp;

import be.ac.ulg.montefiore.run.distributions.GaussianDistribution;
import be.ac.ulg.montefiore.run.jahmm.Observation;
import be.ac.ulg.montefiore.run.jahmm.OpdfGaussian;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.CommandLineArguments;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.Types;
import be.ac.ulg.montefiore.run.jahmm.apps.cli.WrongArgumentsException;
import be.ac.ulg.montefiore.run.jahmm.io.FileFormatException;
import com.em.EMForGaussians;
import com.em.EmForGaussiansResult;
import com.utils.SequenceIterator;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: bigmar
 * Date: 12/9/14
 * Time: 12:07 PM
 * To change this template use File | Settings | File Templates.
 */
public class Main
{
    public static  void main(String[] args) throws Exception
    {
        System.out.print(Math.exp(-2500));
        System.out.println(new Date());
        InputStream seqStream = new FileInputStream("C:\\workspace\\jahmm-0.6.1\\tests\\change2States.seq");
        Reader seqReader = new InputStreamReader(seqStream);
        CommandLineArguments.Arguments.OPDF.set("gaussian");
        CommandLineArguments.Arguments.OPDF.setIsSet(true);
        List<? extends List<? extends Observation>> seqs = Types.relatedObjs().readSequences(seqReader);


        int numberOfModels=2;
        int numberOfObservations=10000;
        SequenceIterator sequenceIterator=new SequenceIterator(seqs, numberOfObservations);
        List<OpdfGaussian> gaussianList=new ArrayList(numberOfModels);



        gaussianList.add(new OpdfGaussian(10, 0.1));
        gaussianList.add(new OpdfGaussian(0, 0.1));
//        gaussianDistributions[3]=new GaussianDistribution(4, 0.01);
        double[] mixtureWeights=new double[numberOfModels];
        mixtureWeights[0]=.5;
        mixtureWeights[1]=.5;
//        mixtureWeights[2]=.43;
        EmForGaussiansResult emForGaussiansResult=new EmForGaussiansResult(mixtureWeights, gaussianList, 1);
        ContionousOutputDistributionEstimator estimator=new ContionousOutputDistributionEstimator(emForGaussiansResult.getGaussianList(), emForGaussiansResult.getMixtureWeights(), sequenceIterator, numberOfObservations);
        double[] etaEstimation=estimator.estimate();

        double[][] kMatrix=OutputDistributionCalculator.calculate(emForGaussiansResult.getGaussianList());

        double [][] cMatrix=CMatrixCalculator.calculate(emForGaussiansResult.getMixtureWeights(), kMatrix);

        double sol[][]=QPCaller.call(cMatrix, emForGaussiansResult.getMixtureWeights(), etaEstimation);
        for (int modelIndex=0; modelIndex<numberOfModels; ++modelIndex)
        {
            System.out.println("State"+(modelIndex+1));
            System.out.println("    Mixture=    "+emForGaussiansResult.getMixtureWeights()[modelIndex]);
            System.out.println("    E=          " + emForGaussiansResult.getGaussianList().get(modelIndex).mean());
            System.out.println("    V=          "+emForGaussiansResult.getGaussianList().get(modelIndex).variance());
            System.out.print(  "    A=          ");
            for (int i=0; i<numberOfModels; ++i)
                System.out.print((double)(Math.round(100*sol[modelIndex][i]))/100+",");
            System.out.println();
        }
    }
}
